package com.imooc.example.order;

import com.imooc.example.order.command.StudentFailCommand;
import com.imooc.example.order.event.StudentFailedEvent;
import com.imooc.example.order.event.StudentFinishedEvent;
import com.imooc.example.order.command.StudentCreateCommand;
import com.imooc.example.order.command.StudentFinishCommand;
import com.imooc.example.order.event.saga.StudentCreatedEvent;
import lombok.extern.slf4j.Slf4j;
import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.commandhandling.model.AggregateIdentifier;
import org.axonframework.eventsourcing.EventSourcingHandler;
import org.axonframework.spring.stereotype.Aggregate;

import java.util.UUID;

import static org.axonframework.commandhandling.model.AggregateLifecycle.apply;

@Slf4j
@Aggregate
public class Student {

    @AggregateIdentifier
    private String id;
    private String ageId;
    private String name;
    private Integer age;
    private String reason;

    public Student() {
    }

    @CommandHandler
    public Student(StudentCreateCommand command) {
        apply(StudentCreatedEvent.builder()
                .studentId(command.getStudentId())
                .name(command.getName()).build());
    }

    @EventSourcingHandler
    public void onCreate(StudentCreatedEvent event) {
        this.id = event.getStudentId();
        this.ageId = UUID.randomUUID().toString();
        this.name = event.getName();
        log.info("赋值对象id = {}", id);
        log.info("赋值对象name = {}", name);
    }

    @CommandHandler
    public Student(StudentFinishCommand command) {
        apply(StudentFinishedEvent.builder()
                .studentId(command.getStudentId())
                .name(command.getName())
                .age(command.getAge()).build());
    }

    @EventSourcingHandler
    public void onFinish(StudentFinishedEvent event) {
        this.id = "finish" + event.getStudentId();
        this.name = event.getName();
        this.age = event.getAge();
        log.info("age = {}", age);
    }

    @CommandHandler
    public Student(StudentFailCommand command) {
        apply(StudentFailedEvent.builder().studentId(command.getStudentId()).reason(command.getReason()).build());
    }

    @EventSourcingHandler
    public void onFail(StudentFailedEvent event) {
        this.id = "fail" + event.getStudentId();
        this.reason = event.getReason();
        log.info("StudentFailedEvent = {}", event);
    }

}
